import numpy as np
import os

# a为M矩阵，b为M帽矩阵(加噪后)
def cVD(a, b):
    c = a - b   #计算两个矩阵的差
    # np.linalg.norm(c)为计算矩阵的范数
    return (np.linalg.norm(c)/np.linalg.norm(a))

#计算RP和RK
def cRP(a, b):
    q = len(a)    #q个对象，相当于行
    p = len(a[0])    #p个属性，相当于列
    sumRP = 0
    sumRK = 0
    #i为行，j为列
    for i in range(q):
        for j in range(p):
            subArray1 = a[0:i + 1, 0:j + 1]     #之前的矩阵提取子项
            subArray2 = b[0:i + 1, 0:j + 1]     #加噪后的矩阵提取子项
            rank1 = np.linalg.matrix_rank(subArray1)    #计算秩
            rank2 = np.linalg.matrix_rank(subArray2)
            #print(rank1, rank2)
            o_o = abs(rank1 - rank2)
            sumRP += o_o    #计算O-O帽
            if o_o ==0:   #如果O-O帽得零则rk=1
                sumRK += 1     #计算Rk的和

    RP = sumRP / p * q   #计算RP值
    RK = sumRK / p * q   #计算RK值
    return RP, RK


#计算cp和CK值
def cCP(a, b):
    p = len(a[0])  # p个属性，相当于列
    sumCP = 0
    sumCK = 0
    for i in range(p):
        subArray1 = a[:, i:i + 1]   #提取出第i+1列
        subArray2 = b[:, i:i + 1]
        rank1 = np.linalg.matrix_rank(subArray1)  # 计算秩
        rank2 = np.linalg.matrix_rank(subArray2)
        # print(rank1, rank2)
        c_c = abs(rank1 - rank2)    #计算CP和
        sumCP += c_c
        if c_c == 0:
            sumCK += 1
    CP = sumCP / p   #计算CP值
    CK = sumCK / p
    return CP, CK


#返回文件夹数组
def getFilepath():
    FilePath = os.path.abspath('.') + "\data\\"
    parents = os.listdir(FilePath)
    files = []
    #获取data文件夹下除了data.txt的其他文件的路径(加噪后的数据文件)
    for parent in parents:
        if parent != "data.txt":
            files.append(parent)
    return files


if __name__ == '__main__':
    datas = getFilepath()   #获取data文件夹下所有文件，即加噪后的数据
    filea = "data.txt"   #源文件文件名
    FilePath = os.path.abspath('.') + "\data\\"
    FilePatha = FilePath + filea    #data.txt是原数据
    a = np.loadtxt(FilePatha, dtype=float, delimiter=',')    #以float加载txt为矩阵形式
    for i in range(len(datas)):
        fileb = FilePath + datas[i]
        b = np.loadtxt(fileb, dtype=float, delimiter=',')
        #分别计算五个参数
        VD = cVD(a, b)
        RP, RK = cRP(a, b)
        CP, CK = cCP(a, b)
        print(filea, datas[i], ":  VD=", VD, ", RP=", RP, ", RK=", RK, ", CP=", CP, ", CK=", CK)

    #a1 = [[2, 4, 5, 0, 3], [5, 1, 7, -6, 8], [1, 4, 9, 5, 2], [5, 0, 3, -6, 4], [4, 8, 0, 6, 5]]
    #b1 = [[2, 0, 6, 4, 1], [4, 6, 0, 3, -1], [4, 8, 2, 1, 5], [4, 6, 3, 0, 8], [7, 4, 6, 0, 5]]
    #a = np.array(a1)
    #b = np.array(b1)

